﻿using RStudio.UnitSingleton;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Pool;

/// <summary>
/// 高性能模型加载服务 - 基于对象池的分帧处理系统
/// 支持基础几何体的高效创建/回收，通过对象池减少GC和性能波动
/// </summary>
public class ServicePrimitiveModelLoader2 : IGameService
{
    /// <summary>服务优先级（值越高越先初始化）</summary>
    public int Priority => 90;

    /// <summary>基础几何体对象池字典（键：几何体类型，值：对应的对象池）</summary>
    private readonly Dictionary<PrimitiveType, IObjectPool<GameObject>> _primitivePools = new();

    /// <summary>自定义模型对象池字典（预留实现）</summary>
    private readonly Dictionary<string, IObjectPool<GameObject>> _customModelPools = new();

    /// <summary>活跃实例集合（用于跟踪当前正在使用的对象）</summary>
    private readonly HashSet<GameObject> _activeInstances = new();

    /// <summary>对象池根节点字典（按几何体类型分组管理）</summary>
    private readonly Dictionary<PrimitiveType, Transform> _primitiveRoots = new();

    /// <summary>创建请求队列（分帧处理用）</summary>
    private readonly Queue<CreateRequest> _createQueue = new Queue<CreateRequest>();

    /// <summary>销毁请求队列（分帧处理用）</summary>
    private readonly Queue<GameObject> _destroyQueue = new Queue<GameObject>();

    /// <summary>队列操作锁（确保线程安全）</summary>
    private readonly object _queueLock = new object();

    /// <summary>性能配置 - 每帧最大处理操作数（防止单帧性能过载）</summary>
    private readonly int _maxOperationsPerFrame = 30;

    /// <summary>预加载总数（每个对象池的基础容量）</summary>
    private readonly int _preloadCount = 200;

    /// <summary>对象池根节点（场景中所有池化对象的父节点）</summary>
    private Transform _poolsRoot;

    /// <summary>是否已释放资源</summary>
    private bool _disposed = false;

    /// <summary>协程运行器（用于驱动分帧处理逻辑）</summary>
    private MonoBehaviour _coroutineRunner;

    /// <summary>创建请求数据结构（封装分帧创建所需的所有参数）</summary>
    private struct CreateRequest
    {
        public PrimitiveType Type;          // 几何体类型
        public Vector3 Position;            // 位置
        public Vector3 Scale;               // 缩放
        public Material Material;           // 材质
        public Action<GameObject> Callback; // 创建完成回调
    }

    /// <summary>初始化服务</summary>
    public void Init()
    {
        InitRoot();          // 初始化根节点
        InitPrimitivePools();// 初始化所有基础几何体对象池
        StartFrameProcessor();// 启动分帧处理器
    }

    /// <summary>释放所有资源</summary>
    public void Dispose()
    {
        if (_disposed) return; // 防止重复释放

        // 停止分帧处理
        StopFrameProcessor();
        // 卸载所有活跃实例
        DoUnload();

        // 清空队列
        lock (_queueLock)
        {
            _createQueue.Clear();
            _destroyQueue.Clear();
        }

        // 清理所有对象池
        foreach (var pool in _primitivePools.Values)
        {
            pool.Clear();
        }
        _primitivePools.Clear();

        foreach (var pool in _customModelPools.Values)
        {
            pool.Clear();
        }
        _customModelPools.Clear();

        // 销毁根节点
        if (_poolsRoot != null)
        {
            UnityEngine.Object.Destroy(_poolsRoot.gameObject);
        }

        _disposed = true;
    }

    #region 初始化相关方法

    /// <summary>初始化根节点和协程运行器</summary>
    private void InitRoot()
    {
        // 创建主根节点（不随场景销毁）
        _poolsRoot = new GameObject("[ModelPools_Root]").transform;
        UnityEngine.Object.DontDestroyOnLoad(_poolsRoot.gameObject);

        // 创建协程运行器（用于执行分帧处理逻辑）
        var runnerObj = new GameObject("[FrameProcessor]");
        runnerObj.transform.SetParent(_poolsRoot);
        _coroutineRunner = runnerObj.AddComponent<CoroutineRunner>();
    }

    /// <summary>启动分帧处理器协程</summary>
    private void StartFrameProcessor()
    {
        if (_coroutineRunner != null)
        {
            _coroutineRunner.StartCoroutine(FrameProcessor());
        }
    }

    /// <summary>停止所有协程</summary>
    private void StopFrameProcessor()
    {
        if (_coroutineRunner != null)
        {
            _coroutineRunner.StopAllCoroutines();
        }
    }

    /// <summary>初始化所有基础几何体的对象池</summary>
    private void InitPrimitivePools()
    {
        // 获取所有PrimitiveType枚举值
        var primitiveTypes = Enum.GetValues(typeof(PrimitiveType)).Cast<PrimitiveType>();
        foreach (var primitiveType in primitiveTypes)
        {
            CreatePrimitivePool(primitiveType);
        }
    }

    /// <summary>为指定几何体类型创建对象池</summary>
    private void CreatePrimitivePool(PrimitiveType primitiveType)
    {
        // 创建该类型的专用根节点
        Transform poolRoot = new GameObject($"Pool|{primitiveType}").transform;
        poolRoot.SetParent(_poolsRoot);
        poolRoot.localPosition = Vector3.zero;
        poolRoot.localRotation = Quaternion.identity;
        _primitiveRoots.TryAdd(primitiveType, poolRoot);

        // 创建对象池
        var pool = new ObjectPool<GameObject>(
            createFunc: () => GameObjectExtension.DoCreatePrimitiveInstance(primitiveType), // 创建新实例的方法
            actionOnGet: target => target.DoGetFromPool(), // 从池获取时的处理
            actionOnRelease: target => target.DoResetToPool(poolRoot), // 释放回池时的处理
            actionOnDestroy: UnityEngine.Object.Destroy, // 销毁实例的方法
            collectionCheck: false, // 关闭集合检查（提升性能）
            defaultCapacity: _preloadCount, // 初始容量
            maxSize: 10000 // 最大容量
        );

        _primitivePools[primitiveType] = pool;

        // 预加载部分实例（预热对象池）
        PreloadPool(pool, Mathf.Min(50, _preloadCount));
    }

    /// <summary>预加载对象到池中</summary>
    private void PreloadPool(IObjectPool<GameObject> pool, int count)
    {
        var preloadList = new List<GameObject>();
        // 先从池获取对象（触发创建）
        for (int i = 0; i < count; i++)
        {
            preloadList.Add(pool.Get());
        }
        // 再释放回池（完成预热）
        foreach (var obj in preloadList)
        {
            pool.Release(obj);
        }
    }

    #endregion

    #region 异步创建/销毁接口（分帧处理）

    /// <summary>
    /// 异步创建基础几何体（加入分帧处理队列）
    /// </summary>
    /// <param name="primitiveType">几何体类型</param>
    /// <param name="position">位置</param>
    /// <param name="scale">缩放（默认1,1,1）</param>
    /// <param name="material">材质</param>
    /// <param name="callback">创建完成回调</param>
    public void DoCreateAsync(
        PrimitiveType primitiveType,
        Vector3 position,
        Vector3? scale = null,
        Material material = null,
        Action<GameObject> callback = null)
    {
        if (_disposed) return; // 已释放则忽略

        // 封装创建请求
        var request = new CreateRequest
        {
            Type = primitiveType,
            Position = position,
            Scale = scale ?? Vector3.one,
            Material = material,
            Callback = callback
        };

        // 线程安全地加入队列
        lock (_queueLock)
        {
            _createQueue.Enqueue(request);
        }
    }

    /// <summary>
    /// 异步批量创建基础几何体
    /// </summary>
    /// <param name="primitiveType">几何体类型</param>
    /// <param name="positions">位置集合</param>
    /// <param name="scale">缩放（默认1,1,1）</param>
    /// <param name="material">材质</param>
    public void DoCreateAsync(
        PrimitiveType primitiveType,
        IEnumerable<Vector3> positions,
        Vector3? scale = null,
        Material material = null)
    {
        foreach (var position in positions)
        {
            DoCreateAsync(primitiveType, position, scale, material);
        }
    }

    /// <summary>
    /// 异步卸载模型（加入分帧处理队列）
    /// </summary>
    /// <param name="model">要卸载的模型</param>
    public void DoUnloadAsync(GameObject model)
    {
        // 验证对象有效性
        if (model == null || !_activeInstances.Contains(model)) return;

        // 线程安全地加入队列
        lock (_queueLock)
        {
            _destroyQueue.Enqueue(model);
        }
    }

    #endregion

    #region 同步创建接口（立即执行）

    /// <summary>
    /// 立即创建基础几何体
    /// </summary>
    /// <param name="primitiveType">几何体类型</param>
    /// <param name="position">位置</param>
    /// <param name="scale">缩放（默认1,1,1）</param>
    /// <param name="material">材质</param>
    /// <returns>创建的几何体实例</returns>
    public GameObject DoCreate(PrimitiveType primitiveType, Vector3 position, Vector3? scale = null, Material material = null)
    {
        if (_disposed) return null;

        // 获取对应对象池
        var pool = GetPrimitivePool(primitiveType);
        if (pool == null) return null;

        // 从池获取实例
        var primitive = pool.Get();
        if (primitive == null) return null;

        // 配置实例属性
        GameObjectExtension.ConfigureForUse(primitive, position, scale ?? Vector3.one, material);
        _activeInstances.Add(primitive);

        return primitive;
    }

    /// <summary>
    /// 立即批量创建基础几何体
    /// </summary>
    /// <param name="primitiveType">几何体类型</param>
    /// <param name="positions">位置集合</param>
    /// <param name="scale">缩放（默认1,1,1）</param>
    /// <param name="material">材质</param>
    /// <returns>创建的几何体实例列表</returns>
    public List<GameObject> DoCreate(PrimitiveType primitiveType, IEnumerable<Vector3> positions,
                                   Vector3? scale = null, Material material = null)
    {
        return positions.Select(pos => DoCreate(primitiveType, pos, scale, material))
                       .Where(obj => obj != null)
                       .ToList();
    }

    #endregion

    #region 卸载与清理接口

    /// <summary>
    /// 立即卸载模型（放回对象池或销毁）
    /// </summary>
    /// <param name="model">要卸载的模型</param>
    public void DoUnload(GameObject model)
    {
        // 验证对象有效性
        if (model == null || !_activeInstances.Contains(model)) return;

        // 尝试放回对应的对象池
        var primitiveType = model.GetPrimitiveType();
        if (primitiveType.HasValue && _primitivePools.TryGetValue(primitiveType.Value, out var pool))
        {
            pool.Release(model);
            _activeInstances.Remove(model);
            return;
        }

        // 无法放回池则直接销毁
        UnityEngine.Object.Destroy(model);
        _activeInstances.Remove(model);
    }

    /// <summary>
    /// 卸载指定类型的所有活跃模型
    /// </summary>
    /// <param name="primitiveType">几何体类型</param>
    public void DoUnload(PrimitiveType primitiveType)
    {
        // 筛选出该类型的所有活跃实例
        var instancesToRemove = _activeInstances
            .Where(obj => GameObjectExtension.IsPrimitiveType(obj, primitiveType))
            .ToList();

        // 逐个卸载
        foreach (var instance in instancesToRemove)
        {
            DoUnload(instance);
        }
    }

    /// <summary>
    /// 卸载所有活跃模型
    /// </summary>
    public void DoUnload()
    {
        // 复制一份列表避免迭代中修改集合
        var instancesToRemove = _activeInstances.ToList();
        foreach (var instance in instancesToRemove)
        {
            DoUnload(instance);
        }
    }

    #endregion

    #region 实例查询接口

    /// <summary>
    /// 获取指定类型的所有活跃实例
    /// </summary>
    /// <param name="primitiveType">几何体类型</param>
    /// <returns>活跃实例列表</returns>
    public List<GameObject> DoGetActives(PrimitiveType primitiveType)
    {
        return _activeInstances
            .Where(obj => GameObjectExtension.IsPrimitiveType(obj, primitiveType))
            .ToList();
    }

    /// <summary>
    /// 获取所有活跃实例
    /// </summary>
    /// <returns>所有活跃实例列表</returns>
    public List<GameObject> DoGetActives()
    {
        return _activeInstances.ToList();
    }

    #endregion

    #region 分帧处理核心逻辑

    /// <summary>分帧处理器协程（每帧处理部分创建/销毁请求）</summary>
    private IEnumerator FrameProcessor()
    {
        while (!_disposed)
        {
            yield return null; // 等待下一帧

            // 处理创建队列
            ProcessCreateQueue();
            // 处理销毁队列
            ProcessDestroyQueue();
        }
    }

    /// <summary>处理创建队列（每帧最多处理_maxOperationsPerFrame个）</summary>
    private void ProcessCreateQueue()
    {
        int processed = 0;

        lock (_queueLock)
        {
            // 处理队列中请求，不超过每帧最大操作数
            while (_createQueue.Count > 0 && processed < _maxOperationsPerFrame)
            {
                var request = _createQueue.Dequeue();
                ProcessSingleCreate(request);
                processed++;
            }
        }

        // 调试信息（可注释）
        // if (processed > 0) Debug.Log($"分帧创建: {processed}个对象");
    }

    /// <summary>处理单个创建请求</summary>
    private void ProcessSingleCreate(CreateRequest request)
    {
        try
        {
            // 获取对象池
            var pool = GetPrimitivePool(request.Type);
            if (pool == null) return;

            // 获取实例并配置
            var primitive = pool.Get();
            if (primitive == null) return;

            GameObjectExtension.ConfigureForUse(primitive, request.Position, request.Scale, request.Material);
            _activeInstances.Add(primitive);

            // 触发回调
            request.Callback?.Invoke(primitive);
        }
        catch (Exception ex)
        {
            Debug.LogError($"创建对象失败: {ex.Message}");
        }
    }

    /// <summary>处理销毁队列（每帧最多处理_maxOperationsPerFrame个）</summary>
    private void ProcessDestroyQueue()
    {
        int processed = 0;

        lock (_queueLock)
        {
            // 处理队列中请求，不超过每帧最大操作数
            while (_destroyQueue.Count > 0 && processed < _maxOperationsPerFrame)
            {
                var model = _destroyQueue.Dequeue();
                if (model != null)
                {
                    DoUnload(model);
                }
                processed++;
            }
        }
    }

    #endregion

    /// <summary>获取指定类型的对象池</summary>
    private IObjectPool<GameObject> GetPrimitivePool(PrimitiveType primitiveType)
    {
        _primitivePools.TryGetValue(primitiveType, out var pool);
        return pool;
    }

    /// <summary>协程运行器组件（用于在非MonoBehaviour类中运行协程）</summary>
    private class CoroutineRunner : MonoBehaviour { }
}